package prefuse.treeview;

import java.awt.BorderLayout;
import java.awt.Checkbox;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import prefuse.Constants;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.Action;
import prefuse.action.ActionList;
import prefuse.action.ItemAction;
import prefuse.action.RepaintAction;
import prefuse.action.animate.ColorAnimator;
import prefuse.action.animate.LocationAnimator;
import prefuse.action.animate.QualityControlAnimator;
import prefuse.action.animate.VisibilityAnimator;
import prefuse.action.assignment.ColorAction;
import prefuse.action.assignment.FontAction;
import prefuse.action.assignment.StrokeAction;
import prefuse.action.filter.FisheyeTreeFilter;
import prefuse.action.layout.AxisLabelLayout;
import prefuse.action.layout.AxisLayout;
import prefuse.action.layout.CollapsedSubtreeLayout;
import prefuse.action.layout.Layout;
import prefuse.action.layout.graph.NodeLinkTreeLayout;
import prefuse.activity.SlowInSlowOutPacer;
import prefuse.controls.ControlAdapter;
import prefuse.controls.FocusControl;
import prefuse.controls.PanControl;
import prefuse.controls.WheelZoomControl;
import prefuse.controls.ZoomControl;
import prefuse.controls.ZoomToFitControl;
import prefuse.data.Schema;
import prefuse.data.Table;
import prefuse.data.Tree;
import prefuse.data.Tuple;
import prefuse.data.event.TupleSetListener;
import prefuse.data.expression.parser.ExpressionParser;
import prefuse.data.io.TreeMLReader;
import prefuse.data.search.KeywordSearchTupleSet;
import prefuse.data.search.SearchTupleSet;
import prefuse.data.tuple.TupleSet;
import prefuse.render.AxisRenderer;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.EdgeRenderer;
import prefuse.render.AbstractShapeRenderer;
import prefuse.render.LabelRenderer;
import prefuse.render.Renderer;
import prefuse.render.ShapeRenderer;
import prefuse.util.ColorLib;
import prefuse.util.FontLib;
import prefuse.util.PrefuseLib;
import prefuse.util.StrokeLib;
import prefuse.util.ui.JSearchPanel;
import prefuse.visual.DecoratorItem;
import prefuse.visual.NodeItem;
import prefuse.visual.VisualItem;
import prefuse.visual.VisualTree;
import prefuse.visual.expression.InGroupPredicate;
import prefuse.visual.expression.VisiblePredicate;
import prefuse.visual.sort.TreeDepthItemSorter;

import prefuse.data.Node;
import prefuse.gui.InterfaceHandler;


/**
 * Demonstration of a node-link tree viewer
 * 
 * @version 1.0
 * @author <a href="http://jheer.org">jeffrey heer</a>
 */
public class TreeViewByInformation extends Display{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

//	public static final String TREE_CHI = "/WNVExampleTree2Week.xml";
	public static String TREE_CHI = "/ann880testresult.xml";
	public static JFrameWin colorPanel;
	public static  InterfaceHandler interfaceHandler;
	public static final String txtFilename = "C:\\tmp\\ann880Test1.txt";
	public static String keyForMap = "";
	public static JComponent display;
	private static final String tree = "tree";
	private static final String treeNodes = "tree.nodes";
	private static final String treeEdges = "tree.edges";
	public static final String EDGE_DECORATORS = "edgeDeco";
    public static final String NODE_DECORATORS = "nodeDeco";
    private int  width = 600;
    private int height = 500;

	private LabelRenderer m_nodeRenderer;
	private EdgeRenderer m_edgeRenderer;
	private static final Schema INFOLABEL_SCHEME = PrefuseLib.getVisualItemSchema(); 
	static { 

    	INFOLABEL_SCHEME.setDefault(VisualItem.FONT, FontLib.getFont("Tahoma", 8));
    }
	private String m_label = "label";
	private int m_orientation = Constants.ORIENT_LEFT_RIGHT;

	// private static String tag = "id";
	// The field here should match the name in
	// if(qName.equals(TREE)&&!(atts.getLength()>0) ) of TreeMLReader.java
	private static String nodeId = "id";
	private static String nodeTime = "time";
	private static String variableName = "variableName";
	private static String nodeType = "name";
	private static String rValue = "rollBackValue";
	private static String tValue = "terminalValue";
	private static String edgeType = "edgeType";
	private static String edgeID = "edgeId";
	private static String eName = "edgeName";
	private static String eValue = "edgeValue";
	private static String eProbability = "probability";
	private static String bestEdgeID = "idOfBestDecision";
	private static TreeMLReader TReaderForCheckBox = null;
	private static JCheckBox ifBestPath = null;
	private static JCheckBox showCurrentNodePath = null;
	private static Table tableForXAxis = new Table();
	// Using info to print each item's information in Jlabel
	private static String info = "";
	private static ItemAction nodeColor;
	private final Rectangle2D boundsLabelsX = new Rectangle2D.Double();
	private static double maxX;
	private static double minX;
	private static Set<Double> staticTimeArray = new HashSet<Double>();
	
	private static Node currentNode = null;
	private static Node previousNode = null;
	private static boolean ifBestSelection = false;
	public static List<Float> arrayForAllValueT = new ArrayList<Float>();
    private static Set<Double> NodesTimeList = new HashSet<Double>();
    private static boolean ifsimulated = false;
	 
	 public static TreeMLReader TReader;
	 
	 
	 public static Color nodeCurrentColor = Color.red;
	 
	public TreeViewByInformation(Tree t, String label) {
		super(new Visualization());
		m_label = label;
		m_vis.add(tree, t);
		Renderer nodeR = new ShapeRenderer(20);
		m_nodeRenderer = new LabelRenderer(m_label);
		m_nodeRenderer.setRenderType(AbstractShapeRenderer.RENDER_TYPE_FILL);
		m_nodeRenderer.setHorizontalAlignment(Constants.LEFT);
		m_nodeRenderer.setRoundedCorner(8, 8);
		m_edgeRenderer = new EdgeRenderer(Constants.EDGE_TYPE_LINE);
		DefaultRendererFactory rf = new DefaultRendererFactory(m_nodeRenderer);//draw the Textfield on each TreeNode
		
		rf.add(new InGroupPredicate(treeEdges), m_edgeRenderer);
		rf.add(new InGroupPredicate(EDGE_DECORATORS), new LabelRenderer(VisualItem.LABEL));
		rf.add(new InGroupPredicate(NODE_DECORATORS), new LabelRenderer(VisualItem.LABEL));
		rf.setDefaultRenderer(nodeR); 
		m_vis.setRendererFactory(rf);

	    INFOLABEL_SCHEME.setDefault(VisualItem.TEXTCOLOR, ColorLib.gray(0));
        m_vis.addDecorators(EDGE_DECORATORS, treeEdges, INFOLABEL_SCHEME);
        INFOLABEL_SCHEME.setDefault(VisualItem.TEXTCOLOR, ColorLib.gray(5));//the blackscale of the Node's fontS
        m_vis.addDecorators(NODE_DECORATORS, treeNodes, INFOLABEL_SCHEME);
        INFOLABEL_SCHEME.setDefault(VisualItem.TEXTCOLOR, ColorLib.gray(255, 128));
    
		 /*This is to shape each node*/
		
		 m_vis.setValue(treeNodes, ExpressionParser.predicate("name='"+"DecisionNode"+"'"), VisualItem.SHAPE,
	                new Integer(Constants.SHAPE_RECTANGLE));
		 m_vis.setValue(treeNodes, ExpressionParser.predicate("name='"+"TerminalNode"+"'"), VisualItem.SHAPE,
	                new Integer(Constants.SHAPE_TRIANGLE_LEFT));
		 m_vis.setValue(treeNodes, ExpressionParser.predicate("name='"+"ChanceNode"+"'"), VisualItem.SHAPE,
	                new Integer(Constants.SHAPE_ELLIPSE));
		// colors
		nodeColor = new NodeColorAction(treeNodes);
		
		ItemAction textColor = new ColorAction(treeNodes, VisualItem.TEXTCOLOR,
				ColorLib.rgb(0, 0, 0));
		m_vis.putAction("textColor", textColor);

		ItemAction nodeStrockColor = new ColorAction(treeNodes, VisualItem.STROKECOLOR,ColorLib.rgb(0, 0, 0));
//		textColor.setDefaultColor(ColorLib.gray(255));
		m_vis.putAction("nodeStrockColor", nodeStrockColor);
		
		ItemAction focusedNodeStroke = new ColorAction(Visualization.FOCUS_ITEMS, VisualItem.STROKECOLOR,ColorLib.rgb(255,100,100));
		ItemAction focusedNodeStrokeSize = new StrokeAction(Visualization.FOCUS_ITEMS,StrokeLib.getStroke(3.0f));
		ItemAction NodeStrokeSize = new StrokeAction(Visualization.ALL_ITEMS,StrokeLib.getStroke(1.0f));
	
		
		m_vis.putAction("focusNodeStroke", focusedNodeStroke);
		m_vis.putAction("focusNodeStrokeSize", focusedNodeStrokeSize);

	
//		m_vis.putAction("textColor", textColor);
	

		ItemAction edgeColor = new EdgeColorAction(treeEdges);
		
//		ItemAction textColor = new ColorAction(treeEdges, VisualItem.TEXTCOLOR,
//				ColorLib.rgb(0, 0, 0));
//		m_vis.putAction("textColor", textColor);
		// quick repaint
		ActionList repaint = new ActionList();
	
		repaint.add(nodeColor);		
		repaint.add(edgeColor);
//		repaint.add(focusedNodeStrokeSize);
//		repaint.add(NodeStrokeSize);
		
		
//		repaint.add(nStroke);
		repaint.add(new RepaintAction());
		m_vis.putAction("repaint", repaint);

		// full paint
		ActionList fullPaint = new ActionList();
		
		fullPaint.add(nodeColor);
		fullPaint.add(edgeColor);
		fullPaint.add(NodeStrokeSize);
		fullPaint.add(focusedNodeStroke);
		fullPaint.add(focusedNodeStrokeSize);
		
		
		m_vis.putAction("fullPaint", fullPaint);

		// animate paint change
		ActionList animatePaint = new ActionList(400);
		animatePaint.add(new ColorAnimator(treeNodes));
		animatePaint.add(new RepaintAction());
		m_vis.putAction("animatePaint", animatePaint);

		// create the tree layout action
		NodeLinkTreeLayout treeLayout = new NodeLinkTreeLayout(tree,
				m_orientation, 50, 5, 8);
//		 Line2D r = new Line2D.Double();
//		 r.setLine(40,50,80,90);
		treeLayout.setLayoutAnchor(new Point2D.Double(10, 300));
	
		m_vis.putAction("treeLayout", treeLayout);

		CollapsedSubtreeLayout subLayout = new CollapsedSubtreeLayout(tree,
				m_orientation);
		m_vis.putAction("subLayout", subLayout);
		
	//	staticTimeArray = timeArray;
		
		tableForXAxis.addColumn("TimeforNode", String.class);
		tableForXAxis.addRows(1);
//		for(int i=0;i<rowNumber;i++){
//			tableForXAxis.set(i,0,133.0);
//		}
		
		String dateText = dayTimeToDate(38987);
		tableForXAxis.set(0,0,dateText);//use fake number to init
//		tableForXAxis.set(1,0,37257.0);
//		tableForXAxis.set(2,0,37287.0);
//		tableForXAxis.set(3,0,37272.0);
		m_vis.addTable("xAxis",tableForXAxis);
		
		rf.add(new InGroupPredicate("xlab"), 
				new AxisRenderer(Constants.CENTER, Constants.TOP));

		AxisLayout x_axis = new AxisLayout("xAxis", "TimeforNode", Constants.X_AXIS,
				VisiblePredicate.TRUE);
//		x_axis.setRangeModel(new NumberRangeModel(1, 8, 1, 8));
		
		
	//	boundsLabelsX.setRect(50, 0, 200, 600);
	//	x_axis.setLayoutBounds(boundsLabelsX);
		
		AxisLabelLayout x_labels = new AxisLabelLayout("xlab", x_axis, boundsLabelsX, 140);//You can change the spacing the minimum spacing between axis labels
	

		ActionList draw = new ActionList();
		draw.add(x_axis);   //draw point
		draw.add(x_labels);
		draw.add(new RepaintAction());
		m_vis.putAction("xAxis", draw);
		m_vis.run("xAxis");
		

		AutoPanAction autoPan = new AutoPanAction(boundsLabelsX);
		
		// create the filtering and layout
		ActionList filter = new ActionList();
		filter.add(new FisheyeTreeFilter(tree, 2));
		filter.add(new FontAction(treeNodes, FontLib.getFont("Tahoma", 16)));
		filter.add(treeLayout);
		filter.add(subLayout);
		filter.add(textColor);
		filter.add(nodeStrockColor);
		filter.add(nodeColor);
		filter.add(edgeColor);
		m_vis.putAction("filter", filter);

		// animated transition
		ActionList animate = new ActionList(1000);
		animate.setPacingFunction(new SlowInSlowOutPacer());
		animate.add(autoPan);
		animate.add(new QualityControlAnimator());
		animate.add(new VisibilityAnimator(tree));
		animate.add(new LocationAnimator(treeNodes));
		animate.add(new ColorAnimator(treeNodes));
		animate.add(new RepaintAction());
		animate.add(new LabelLayout2(EDGE_DECORATORS));
		animate.add(new LabelLayout2(NODE_DECORATORS));
		m_vis.putAction("animate", animate);
		m_vis.alwaysRunAfter("filter", "animate");

		// create animator for orientation changes
		ActionList orient = new ActionList(2000);
		orient.setPacingFunction(new SlowInSlowOutPacer());
		orient.add(autoPan);
		orient.add(new QualityControlAnimator());
		orient.add(new LocationAnimator(treeNodes));
		orient.add(new RepaintAction());
		m_vis.putAction("orient", orient);
		
		
		// ------------------------------------------------

		// initialize the display************************************************************************************************
		setSize(width, height);
		setItemSorter(new TreeDepthItemSorter());

		addControlListener(new ZoomToFitControl());
		addControlListener(new ZoomControl());
		addControlListener(new WheelZoomControl());
		addControlListener(new PanControl());
		addControlListener(new FocusControl(1, "filter"));
		
		
		
		   // create a new JSplitPane to present the interface
//        JSplitPane split = new JSplitPane();
//        split.setLeftComponent(this);
//   //     split.setRightComponent(fpanel);
//        split.setOneTouchExpandable(true);
//        split.setContinuousLayout(false);
//        split.setDividerLocation(700);

		registerKeyboardAction(new OrientAction(Constants.ORIENT_LEFT_RIGHT),
				"left-to-right", KeyStroke.getKeyStroke("ctrl 1"), WHEN_FOCUSED);
		registerKeyboardAction(new OrientAction(Constants.ORIENT_TOP_BOTTOM),
				"top-to-bottom", KeyStroke.getKeyStroke("ctrl 2"), WHEN_FOCUSED);
		registerKeyboardAction(new OrientAction(Constants.ORIENT_RIGHT_LEFT),
				"right-to-left", KeyStroke.getKeyStroke("ctrl 3"), WHEN_FOCUSED);
		registerKeyboardAction(new OrientAction(Constants.ORIENT_BOTTOM_TOP),
				"bottom-to-top", KeyStroke.getKeyStroke("ctrl 4"), WHEN_FOCUSED);

		// ------------------------------------------------
//		 JSplitPane splitPane = new JSplitPane();
//		    splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
//		
		

		// filter graph and perform layout
		setOrientation(m_orientation);
		m_vis.run("filter");
//		add(splitPane);
//		
		TupleSet search = new KeywordSearchTupleSet(); // search method is
														// here,it has Regular
														// Expression/prefix
														// options
		m_vis.addFocusGroup(Visualization.SEARCH_ITEMS, search);
		search.addTupleSetListener(new TupleSetListener() {
			public void tupleSetChanged(TupleSet t, Tuple[] add, Tuple[] rem) {
				m_vis.cancel("animatePaint");
				m_vis.run("fullPaint");
				m_vis.run("animatePaint");
				m_vis.run("xAxis");
			}
		});
		
		 
	
	}
	
	
	
	// ------------------------------------------------------------------------

	public Set<Double> getList(){
		Set<Double> numberList = nodeColor.getList();	
		return numberList;
	}
	
	public void setTableSize(Set<Double> timeArray){
		tableForXAxis.clear();
		tableForXAxis.addRows(timeArray.size());
		
	}
	
//	public void setRect(double maxX){
//		boundsLabelsX.setRect(100, 0, maxX, 600);
//	}
	public void setOrientation(int orientation) {
		NodeLinkTreeLayout rtl = (NodeLinkTreeLayout) m_vis
				.getAction("treeLayout");
		CollapsedSubtreeLayout stl = (CollapsedSubtreeLayout) m_vis
				.getAction("subLayout");
		switch (orientation) {
		case Constants.ORIENT_LEFT_RIGHT:
			m_nodeRenderer.setHorizontalAlignment(Constants.LEFT);
			m_edgeRenderer.setHorizontalAlignment1(Constants.RIGHT);
			m_edgeRenderer.setHorizontalAlignment2(Constants.LEFT);
			m_edgeRenderer.setVerticalAlignment1(Constants.CENTER);
			m_edgeRenderer.setVerticalAlignment2(Constants.CENTER);
			break;
		case Constants.ORIENT_RIGHT_LEFT:
			m_nodeRenderer.setHorizontalAlignment(Constants.RIGHT);
			m_edgeRenderer.setHorizontalAlignment1(Constants.LEFT);
			m_edgeRenderer.setHorizontalAlignment2(Constants.RIGHT);
			m_edgeRenderer.setVerticalAlignment1(Constants.CENTER);
			m_edgeRenderer.setVerticalAlignment2(Constants.CENTER);
			break;
		case Constants.ORIENT_TOP_BOTTOM:
			m_nodeRenderer.setHorizontalAlignment(Constants.CENTER);
			m_edgeRenderer.setHorizontalAlignment1(Constants.CENTER);
			m_edgeRenderer.setHorizontalAlignment2(Constants.CENTER);
			m_edgeRenderer.setVerticalAlignment1(Constants.BOTTOM);
			m_edgeRenderer.setVerticalAlignment2(Constants.TOP);
			break;
		case Constants.ORIENT_BOTTOM_TOP:
			m_nodeRenderer.setHorizontalAlignment(Constants.CENTER);
			m_edgeRenderer.setHorizontalAlignment1(Constants.CENTER);
			m_edgeRenderer.setHorizontalAlignment2(Constants.CENTER);
			m_edgeRenderer.setVerticalAlignment1(Constants.TOP);
			m_edgeRenderer.setVerticalAlignment2(Constants.BOTTOM);
			break;
		default:
			throw new IllegalArgumentException(
					"Unrecognized orientation value: " + orientation);
		}
		m_orientation = orientation;
		rtl.setOrientation(orientation);
		stl.setOrientation(orientation);
	}

	public int getOrientation() {
		return m_orientation;
	}
	public void setGraph(Tree t, String label) {
        // update labeling
		final TreeViewByInformation tview = new TreeViewByInformation(t, label);
		Visualization vis = tview.getVisualization();
        DefaultRendererFactory drf = (DefaultRendererFactory)vis.getRendererFactory();
        ((LabelRenderer)drf.getDefaultRenderer()).setTextField(label);
        
        // update graph
        vis.removeGroup(label);
        VisualTree vg = vis.addTree(tree, t);
     //   m_vis.setValue(edges, null, VisualItem.INTERACTIVE, Boolean.FALSE);
        VisualItem f = (VisualItem)vg.getNode(0);
        vis.getGroup(Visualization.FOCUS_ITEMS).setTuple(f);
        f.setFixed(false);
    }
	// ------------------------------------------------------------------------

	public static void main(String argv[]) {
		String infile = TREE_CHI;
		String label = "name";
		if (argv.length > 1) {
			infile = argv[0];
			label = argv[1]; // label is the fist element of the array
		}
		JFrameWin colorPanel = new JFrameWin();
		JComponent treeview = demo(infile, label,colorPanel,interfaceHandler);

		JFrame frame = new JFrame("DecisionTreeView");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setContentPane(treeview);
		frame.pack();
		frame.setVisible(true);
		
		
	}

	public static JComponent TreePicture() {
		return demo(TREE_CHI, "name", colorPanel,interfaceHandler);
	}

	public static JComponent demo(String datafile, final String label , JFrameWin colorPane, final InterfaceHandler interfaceHandler) {
		

		Color BACKGROUND = Color.WHITE;
		Color FOREGROUND = Color.BLACK;
	//	TreeMLReader TReader = null; // Wenyi add this field in order to get the
										// quaryArray

		Tree t = null;
		
		colorPanel = colorPane;
		
		
	//	colorPanel.colorChooser.getSelectionModel().addChangeListener(this);
	//	JMenu dataMenu = new JMenu("Data");
	 
		try {
			TReader = new TreeMLReader();
			TReaderForCheckBox = TReader;
			t = (Tree) TReader.readGraph(datafile);
			arrayForAllValueT = TReader.arrayForAllValue;
			Collections.sort(arrayForAllValueT);
			System.out.println(arrayForAllValueT);
			
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}

		// create a new treemap
		final TreeViewByInformation tview = new TreeViewByInformation(t, label);
		tview.setBackground(BACKGROUND);
		tview.setForeground(FOREGROUND);
	  //  dataMenu.add(new OpenGraphAction(tview));
			
		JSearchPanel search = new JSearchPanel(tview.getVisualization(),treeEdges, Visualization.SEARCH_ITEMS, edgeID, true, true);
		System.out.println("I am here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
		
		
	
//*******************************************************************************************************************************
//		tview.getList();
//		double max = Collections.max(( tview.getList()));
//		System.out.println(tview.getList() + "ann letters must be sent to: " + tview.getList());
//		System.out.println(tview.getList() + "ann the largest number is: " + max);
//		tview.setRect(maxX);
//*******************************************************************************************************************************		
		search.setShowResultCount(true);
		search.setBorder(BorderFactory.createEmptyBorder(5, 5, 4, 0));
		search.setFont(FontLib.getFont("Tahoma", Font.PLAIN, 11));
		search.setBackground(BACKGROUND);
		search.setForeground(FOREGROUND);
		
		ifBestPath = new JCheckBox("High Light The Best Path");
		showCurrentNodePath = new JCheckBox("Show path to current Node");

		final JTextArea title = new JTextArea("                 ");

		title.setPreferredSize(new Dimension(350, 70));
		// title.setVerticalAlignment(SwingConstants.BOTTOM);
		title.setAlignmentY(Component.BOTTOM_ALIGNMENT);
		title.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));
		title.setFont(FontLib.getFont("Tahoma", Font.PLAIN, 12));
		title.setLineWrap(true);
		title.setWrapStyleWord(true);
		title.setEditable(false);
		title.setBackground(BACKGROUND);
		title.setForeground(FOREGROUND);

		
		colorPanel.colorChooser.getSelectionModel().addChangeListener(
			    new ChangeListener() {
				public void stateChanged(ChangeEvent e) {
					nodeCurrentColor = colorPanel.colorChooser.getColor();
					tview.getVisualization().run("repaint");
				    System.out.println("mimi " + nodeCurrentColor);
				//    banner.setColor(newColor);
				}
			    }    
			);
		
		

		/*
		 * This function is used to high light all the best decision branch
		 */

		ifBestPath.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				Visualization vis = tview.getVisualization();
				String queryArray[] = TReaderForCheckBox.quaryArray;
				SearchTupleSet m_searcher = (SearchTupleSet) vis
						.getGroup(Visualization.SEARCH_ITEMS);
				
				if (ifBestPath.isSelected()) {
					
					showCurrentNodePath.setEnabled(false);
					synchronized (vis) {
						ifBestSelection = true;
						m_searcher.searchForArray(queryArray);
						
						
					}

				} else if (!ifBestPath.isSelected()) {
					ifBestSelection = false;
					showCurrentNodePath.setEnabled(true);
					synchronized (vis) {
						m_searcher.CancelSearchForArray(queryArray);
					
					}

				}
			}
		});
		/*When showCurrentNodePath had been selected , unable the check box ifBestPath
		 * writen by Wenyi AN
		 * */
		showCurrentNodePath.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
			
				if (showCurrentNodePath.isSelected()) {				
					ifBestPath.setEnabled(false);
				

				} else if (!showCurrentNodePath.isSelected()) {
					ifBestPath.setEnabled(true);
				

				}
			}
		});

		tview.addControlListener(new ControlAdapter() {
			public void itemEntered(VisualItem item, MouseEvent e) {
				if (item.canGetString(nodeId)) {
					info = "NodeId: " + item.getString(nodeId);
					title.setText(info);
				}
				if (item.canGetString(nodeTime)) {
					info =  info +"  " +"NodeTime: " + item.getString(nodeTime);
					title.setText(info);
				}
				
				if (item.canGetString(variableName)) {
					info =  info +"  " +"NodeVariableName: " + item.getString(variableName);
					title.setText(info);
				}
				
				if (item.canGetString(rValue)&&!item.get(nodeType).equals("TerminalNode")) {
					info = info + "  " + "\nNodeRollbackValue : "
							+ item.getString(rValue);
					title.setText(info);
				}
				if (item.canGetString(tValue)&&item.get(nodeType).equals("TerminalNode")) {
					info = info + "  " + "NodeTerminalValue : "
							+ item.getString(tValue);
					title.setText(info);
				}
				if (item.canGetString(bestEdgeID)) {
					info = info + "\nBestEdgeID: " + item.getString(bestEdgeID);
					title.setText(info);
				}

				if (item.canGetString(edgeID)) {
					info = "EdgeID: " + item.getString(edgeID);
					title.setText(info);
				}
				if (item.canGetString(edgeType)) {
					info = info + "  " + "\nEdgeType: "
							+ item.getString(edgeType);
					title.setText(info);
				}
				if (item.canGetString(eName)) {
					info = info + "  " +"EdgeName: " + item.getString(eName);
					title.setText(info);
				}
				if (item.canGetString(eValue)) {
					info = info + "  " +"\nEdgeValue: " + item.getString(eValue);
					title.setText(info);
				}
				if (item.canGetString(eProbability)&&item.get(edgeType).equals("ChanceEdge")) {
					info = info + "  " +"Probability: " + item.getString(eProbability);
					title.setText(info);
				}

			}

			public void itemExited(VisualItem item, MouseEvent e) {
				title.setText(null);
			}
			 public void itemClicked(VisualItem item, MouseEvent e) 
	            {
				 	if(item instanceof NodeItem && item.get(nodeType).equals("TerminalNode")){
				 		int terminalNodeId = -1;
				 		currentNode = (Node)item;
						if(currentNode!=previousNode){
							CancelShowPathInfoForTerminalNode(previousNode);

						}
				 		ShowPathInfo((Node)item);			 		
				 		previousNode = currentNode;
				 		
				 		terminalNodeId = currentNode.getInt(nodeId);
				 		System.out.println("terminalNodeId: "+terminalNodeId);
				 		
				 		if(!ifsimulated){
				 			interfaceHandler.run();
				 			ifsimulated = true;
				 		}
				 		int nodeBranchID = currentNode.getInt(nodeId);
				 		System.out.println("current Node Id : "+nodeBranchID);
				 		interfaceHandler.setVdfFileName("C:\\tmp\\Default simulation_Branch_"+nodeBranchID+".vdf");
				 		
				 	}
				 	
				 	if(item instanceof NodeItem && !item.get(nodeType).equals("TerminalNode")){
				 		CancelShowPathInfoForTerminalNode(previousNode);
				 	}
	               
	            }
			 /*
				 * This function is show the info of the current path
				 * writen by Wenyi AN
				 */
				public void ShowPathInfo(Node focusNode){
					//save every BestDecision Edge Id into quaryArray
					//Writen by Wenyi AN
					if (focusNode == null){
						return;
					}
					else{		
						tview.getVisualization().getGroup("tree").addColumn(VisualItem.LABEL, String.class);				
					while(focusNode.getRow()!=0){
						if(focusNode.get(nodeType).equals("TerminalNode")){//if the node is terminal print terminal value
							float tempTValue = focusNode.getFloat(tValue);							
							String tempStringTValue = String.valueOf(tempTValue );														
							focusNode.setString(VisualItem.LABEL,tempStringTValue);
							focusNode.getParentEdge().setString(VisualItem.LABEL,focusNode.getParentEdge().getString(eName));
							focusNode = focusNode.getParent();
						}
						else{
							float tempRValue = focusNode.getFloat(rValue);							
							String tempStringRValue = String.valueOf(tempRValue );	// Transfer it to string cause dont want show "f" at the 
																					//end of the number
							focusNode.setString(VisualItem.LABEL,tempStringRValue); //otherwise print the rollback value
							focusNode.getParentEdge().setString(VisualItem.LABEL,focusNode.getParentEdge().getString(eName));
							focusNode = focusNode.getParent();
						}
					}
						float tempRValue = focusNode.getFloat(rValue);							
						String tempStringRValue = String.valueOf(tempRValue );	// Transfer it to string cause dont want show "f" at the 
																				//end of the number
						focusNode.setString(VisualItem.LABEL,tempStringRValue);
					}
					focusNode = currentNode; //this command for high light the TerminalNode
				}
				
				/*
				 * This function is erase the information from RootNode to Terminal Node
				 * writen by Wenyi AN
				 */
				public void CancelShowPathInfoForTerminalNode(Node previousNode){
					
					if (previousNode == null){
						return;
					}
					else{		
						tview.getVisualization().getGroup("tree").addColumn(VisualItem.LABEL, String.class);
					while(previousNode.getRow()!=0){
							previousNode.setString(VisualItem.LABEL,null);
							previousNode.getParentEdge().setString(VisualItem.LABEL,null);
							previousNode = previousNode.getParent();
					}
					
					previousNode.setString(VisualItem.LABEL,null);

					}
					previousNode = currentNode; //this command for high light the TerminalNode
				}
		});
		
		
		
		
		Box box = new Box(BoxLayout.Y_AXIS);
	
		box.add(title);
		box.add(ifBestPath);
		box.add(showCurrentNodePath);
		box.setBackground(BACKGROUND);
	
		
		JPanel panel = new JPanel(new BorderLayout());
		panel.setBackground(BACKGROUND);
		panel.setForeground(FOREGROUND);
		panel.add(tview, BorderLayout.CENTER);
		panel.add(box, BorderLayout.SOUTH);
		
		

		
	//	JMenuBar menubar = new JMenuBar();
	 //   menubar.add(dataMenu);
		
		
//		JFrame frame = new JFrame("DecisionTreeView");
//		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//	//    frame.setJMenuBar(menubar);
//		frame.setContentPane(panel);
//		JSplitPane splitPane = new JSplitPane();
//		splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
//	//	splitPane.setLeftComponent(panel);
////		splitPane.setOneTouchExpandable(true);
////		splitPane.setContinuousLayout(false);
////		splitPane.setDividerLocation(700);
//		frame.getContentPane().add(splitPane);
//		frame.pack();
//		frame.setVisible(true);
		
		
	
			
		return panel;

	}
	
	
	
	 public static Set<Double> getTimeListSet(){
		 NodesTimeList = TReader.NodesTimeList;
     	return NodesTimeList;
     }

	// ------------------------------------------------------------------------
	/**
	 * Set label positions. Labels are assumed to be DecoratorItem instances,
	 * decorating their respective nodes. The layout simply gets the bounds
	 * of the decorated node and assigns the label coordinates to the center
	 * of those bounds.
	 */
	class LabelLayout2 extends Layout {
	    public LabelLayout2(String group) {
	        super(group);
	    }
	    public void run(double frac) {
	        Iterator iter = m_vis.items(m_group);
	        while ( iter.hasNext() ) {
	            DecoratorItem decorator = (DecoratorItem)iter.next();
	            VisualItem decoratedItem = decorator.getDecoratedItem();
	            Rectangle2D bounds = decoratedItem.getBounds();
	            double x = bounds.getCenterX();
	            double y = bounds.getCenterY();
	            /* modification to move edge labels more to the arrow head
	            double x2 = 0, y2 = 0;
	            if (decoratedItem instanceof EdgeItem){
	            	VisualItem dest = ((EdgeItem)decoratedItem).getTargetItem(); 
	            	x2 = dest.getX();
	            	y2 = dest.getY();
	            	x = (x + x2) / 2;
	            	y = (y + y2) / 2;
	            }
	            */
	            setX(decorator, null, x);
	            setY(decorator, null, y);
	        }
	    }
	} // end of inner class LabelLayout	

	public class OrientAction extends AbstractAction {
		private int orientation;

		public OrientAction(int orientation) {
			this.orientation = orientation;
		}

		public void actionPerformed(ActionEvent evt) {
			setOrientation(orientation);
			getVisualization().cancel("orient");
			getVisualization().run("treeLayout");
			getVisualization().run("orient");
		}
	}
	
	private static String dayTimeToDate(int dayN) {
		int dayNumber = dayN ;
		Calendar origin = Calendar.getInstance();
		origin.set(1900, 00, 00); // init a origin calendar.
		origin.add(Calendar.DAY_OF_YEAR, dayNumber);
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = format.format(origin.getTime());
		System.out.println("Today is:" + dateString);
		return dateString;

	}

	public class AutoPanAction extends Action {
		
	
		private Point2D m_start = new Point2D.Double();
		private Point2D m_end = new Point2D.Double();
		private Point2D m_cur = new Point2D.Double();
		private int m_bias = 150;
		private Node focusNode = null;
		private Node CurrentNode = null;
		private String[] partentEdgeList = new String[]{};
		private Double [] NodesTimeListArray;
		private int parentEdgeRowNumber = -1;
		private String parentEdgeName;
		private double CurNodeTime = 0.0;
//		private TableCreater tableCreater = new TableCreater();
//		private JFrame TableTerminal=null;
	
//		private Rectangle2D labelsX;
		
		public AutoPanAction(Rectangle2D boundsLabelsX){
//			labelsX = boundsLabelsX;
		}

		public void run(double frac) {		
			TupleSet ts = m_vis.getFocusGroup(Visualization.FOCUS_ITEMS);
		
			if (ts.getTupleCount() == 0){
				return;}

			if (frac == 0.0) {
				int xbias = 0, ybias = 0;
				switch (m_orientation) {
				case Constants.ORIENT_LEFT_RIGHT:
					xbias = m_bias;
					break;
				case Constants.ORIENT_RIGHT_LEFT:
					xbias = -m_bias;
					break;
				case Constants.ORIENT_TOP_BOTTOM:
					ybias = m_bias;
					break;
				case Constants.ORIENT_BOTTOM_TOP:
					ybias = -m_bias;
					break;
				}
				
				
				VisualItem vi = (VisualItem) ts.tuples().next();
	
				 if (vi instanceof Node){
					 focusNode = (Node) ts.tuples().next();
					 boundsLabelsX.setRect(minX, 0, (maxX-10), 600); // this is the table in the tree view, 10 is half size of a node
					 tableForXAxis.clear();		//very important!!!		 
					 tableForXAxis.addRows(staticTimeArray.size());

					int i = 0;//recirle 
					
					  for (double temp : staticTimeArray){
						  
						 String tempDate =  dayTimeToDate((int)Math.rint(temp));
						  tableForXAxis.set(i,0,tempDate);
						  i++;
					  }
				//	 i=0;
					
					System.out.println("staticTimeArray.size() is : " + staticTimeArray.size());
					 
					 
					 if(focusNode.get(nodeType).equals("TerminalNode")){
//						System.err.println("this is a terminal Node!");				
				//		 ShowPathInfo();
					 }
				 }
				
				
				if(focusNode.get(nodeType).equals("TerminalNode")){
					keyForMap = (String) focusNode.get(variableName);
//					if(TableTerminal!=null){
//						TableTerminal.dispose();
//					}
//					System.err.println("this is a terminal Node!");					
				
	//				CurrentNode = focusNode;
	//				getTimeList();
	//				ShowPathInfo();
	//				DrawPathToNode();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////					
//					m_vis.getGroup("tree").addColumn(VisualItem.LABEL, String.class);
//			    	for (int i = 0; i < 9; i++) {		
//			    		Tree testT;			    		
//			    		testT = (Tree) m_vis.getGroup("tree");
//			    		testT.getNode(i).setString(VisualItem.LABEL, ""+i);
//			    		testT.getEdge(i).setString(VisualItem.LABEL, ""+i);
//			    		
//					}
				
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
//					Table table;
			
//						try {
//							System.out.println("NodesTimeList: "+NodesTimeList.size());
//							NodesTimeListArray = (Double[]) NodesTimeList.toArray();
//							
//							table = TableCreater.generateTable(txtFilename,keyForMap,NodesTimeListArray);
//							display = TableCreater.createVisualization(table);
//							javax.swing.SwingUtilities.invokeLater(new Runnable() {
//								public void run() {
//
//									TableTerminal = TableCreater.createAndShowGUI(display,keyForMap);
////									TableTerminal.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//when the sub window been closed the bigger not close
//								}
//							});					
//						} catch (IOException e) {
//							// TODO Auto-generated catch block
//							e.printStackTrace();
//						}		
//					focusNode = CurrentNode; //this command for high light the TerminalNode
				}//Terminal Node function finish
				
//				if(TableTerminal!=null){
//					TableTerminal.dispose();
//				}
			
			
				partentEdgeList = new String[]{};
				if(showCurrentNodePath.isSelected()){
					ifBestPath.setEnabled(false);
					DrawPathToNode();
				}
				else{
					ifBestPath.setEnabled(true);
					CancelDrawPathToNode();
				}
			
			/*
			 * This part of code let the focus node move to the middle of the screen
			 * */	
			
//				m_cur.setLocation(getWidth() / 2, getHeight() / 2);
//				getAbsoluteCoordinate(m_cur, m_start);
//				m_end.setLocation(vi.getX() + xbias, vi.getY() + ybias);
//			} else {
//				m_cur.setLocation(m_start.getX() + frac
//						* (m_end.getX() - m_start.getX()), m_start.getY()
//						+ frac * (m_end.getY() - m_start.getY()));
//				panToAbs(m_cur);
			}
		}
		
//		public void getTimeList(){
//			if (focusNode == null){
//				return;
//			}
//			else{
//				while(focusNode.getRow()!=0){
//					CurNodeTime = (Double) focusNode.get(nodeTime);
//					System.out.println("the time of each node: " + CurNodeTime);
//					if(NodesTimeList==null){
//				//		NodesTimeList[0] = CurNodeTime;		
//						NodesTimeList.add(CurNodeTime);
//						focusNode = focusNode.getParent();				
//						break;
//					}
//					else{
////						NodesTimeList=Arrays.copyOf(NodesTimeList, NodesTimeList.length+1);
////						NodesTimeList[NodesTimeList.length-1]=CurNodeTime;
//						NodesTimeList.add(CurNodeTime);
//						focusNode = focusNode.getParent();
//					}
//				}
//				if(focusNode.getRow()==0){
//					CurNodeTime = (Double) focusNode.get(nodeTime);
//				//	NodesTimeList=Arrays.copyOf(NodesTimeList, NodesTimeList.length+1);
////					NodesTimeList[NodesTimeList.length-1]=CurNodeTime;
//					NodesTimeList.add(CurNodeTime);
//				}
//			}
//		//	focusNode = CurrentNode; //this command for high light the TerminalNode
//		}
		/*
		 * This function is used to high light all the best decision branch
		 * writen by Wenyi AN
		 */
		public void DrawPathToNode(){
			//save every BestDecision Edge Id into quaryArray
			//Writen by Wenyi AN
			if (focusNode == null){
			//	System.out.println("hahahahahha");
				return;
			}
			else{
			while(focusNode.getRow()!=0){
			//	System.out.println("hehe haha");
				parentEdgeRowNumber = (Integer) focusNode.getParentEdge().get(edgeID);
				
				if(partentEdgeList==null){
			
					partentEdgeList[0] = Integer.toString(parentEdgeRowNumber);
					focusNode = focusNode.getParent();
				
					break;
				}
				else{
			
					partentEdgeList=Arrays.copyOf(partentEdgeList, partentEdgeList.length+1);
					partentEdgeList[partentEdgeList.length-1]=Integer.toString(parentEdgeRowNumber);
					focusNode = focusNode.getParent();
				}
			}
			
			
			if(partentEdgeList!=null){
				SearchTupleSet m_searcher = (SearchTupleSet) m_vis
						.getGroup(Visualization.SEARCH_ITEMS);
				synchronized (m_vis) {
					m_searcher.searchForArray(partentEdgeList);
				}
			}
			}
		}
		

		public void CancelDrawPathToNode(){
			//save every BestDecision Edge Id into quaryArray
			//Writen by Wenyi AN
			if (focusNode == null){
				return;
			}						
			
			if(partentEdgeList!=null){
				SearchTupleSet m_searcher = (SearchTupleSet) m_vis
						.getGroup(Visualization.SEARCH_ITEMS);		
				synchronized (m_vis) {
					m_searcher.CancelSearchForArray(partentEdgeList);
				}
			}
		
		}
		
	}

	

	
	
	public static class NodeColorAction extends ColorAction {
		 public  Set<Double> nodesXLocation = new HashSet<Double>();
		public NodeColorAction(String group) {
			super(group, VisualItem.FILLCOLOR);
			nodesXLocation = new HashSet<Double>();
		}
	
		public int getColor(VisualItem item) {
		
			if (m_vis.isInGroup(item, Visualization.SEARCH_ITEMS))
				return ColorLib.rgb(255, 190, 190);
//			else if (m_vis.isInGroup(item, Visualization.FOCUS_ITEMS)){
//				  ColorAction aStroke = new ColorAction(Visualization.FOCUS_ITEMS, VisualItem.STROKECOLOR);
//			  //  aStroke.setDefaultColor(ColorLib.gray(200));
//			        aStroke.add("_hover", ColorLib.rgb(255,100,100));
//			      //  return ColorLib.rgb(204, 153, 255);  //purple
//			        return 0;
//			}
				
			
			/* this funtion is for highlight the path from the root nood to the current
			 * focused node
			 * */
//			else if (item.getDOI() > -1){//this is rootNode  
//				System.out.println("it is get rootNode x: ");
//				item.get(nodeTime);
//				
//				letter.add(item.getX());
//				staticTimeArray.add((Double) item.get(nodeTime));
//				return ColorLib.hsb((float)0.8, 1,  1);
//			}
			else //those are the other nodes except root Node
				{
				
				nodesXLocation.add(item.getX());
				staticTimeArray.add((Double) item.get(nodeTime));
				Iterator iterator = nodesXLocation.iterator();
				while (iterator.hasNext()){  
			        Object val = iterator.next();  
			        System.out.println("XLocation: "+ val);  
			}  
				maxX = Collections.max(nodesXLocation);
				System.out.println("maxX: "+maxX);
				minX = Collections.min(nodesXLocation);
				System.out.println("minX: "+minX);
					if(item.getString(nodeType).equals("TerminalNode")){
						float TerminalValue =  item.getFloat(tValue);		
						int tValuePosition = arrayForAllValueT.indexOf(TerminalValue);
							System.out.println("tValuePosition "+tValuePosition);
						float TerNodeColor =(float) (tValuePosition*(1.0/arrayForAllValueT.size()*255));
						int redColor = (int) Math.rint(TerNodeColor);
			
						nodeCurrentColor.getRed();
						//nodeCurrentColor.
						return ColorLib.rgb(redColor,nodeCurrentColor.getGreen() ,nodeCurrentColor.getBlue());
					}
					else{
						float NodeRollbackValue =  item.getFloat(rValue);	
						System.out.println("NodeRollbackValueNodeRollbackValue"+NodeRollbackValue);
						int rollBackValuePosition = arrayForAllValueT.indexOf(NodeRollbackValue);
							System.out.println("rollBackValuePosition "+rollBackValuePosition);
						float nodeColor =(float) (rollBackValuePosition*(1.0/arrayForAllValueT.size()*255));
						
						int redColor = (int) Math.rint(nodeColor);
					
						return ColorLib.rgb(redColor,nodeCurrentColor.getGreen() ,nodeCurrentColor.getBlue());
					//	return ColorLib.rgb(169, 225, 182); // the current's node color GREEN
					}
				}
			
		}
		

		

	} // end of inner class TreeMapColorAction

	/**
	 * This is paint the color of Edges Writen by Wenyi AN
	 * 
	 **/
	public static class EdgeColorAction extends ColorAction {

		public EdgeColorAction(String group) {
			super(group, VisualItem.STROKECOLOR, ColorLib.rgb(120, 200, 200));
		}

		public int getColor(VisualItem item) {
			m_vis.getVisualGroup("tree").addColumn(VisualItem.LABEL, String.class);
			if (m_vis.isInGroup(item, Visualization.SEARCH_ITEMS)){
				item.setSize(3);//bold the lines															
				item.setString(VisualItem.LABEL,item.getString(eName)); //it will show info of each edge when best path or selected path
				System.out.println("This is ifBestSelection = true");
			
				return ColorLib.rgb(255, 0, 0);
				}// color is RED
			else if (m_vis.isInGroup(item, Visualization.FOCUS_ITEMS)){		
				item.setSize(3);//bold the lines
				return ColorLib.rgb(0, 255, 100);}
			else if (item.getDOI() > -1){
				item.setSize(1);
			//	item.setString(VisualItem.LABEL,null);
				return ColorLib.rgb(164, 193, 193);}
			else{
				item.setSize(1);
				item.setString(VisualItem.LABEL,null);
				return ColorLib.rgb(120, 200, 200); // defaultcolor
			}
		}

	} // end of inner class TreeMapColorAction


} // end of class TreeMap
